<!DOCTYPE html> 
<html> 
<head> 
 <title>ESP32 Control Panel</title> 
 <style> 
 body { font-family: Arial, sans-serif; } 
 .status { margin: 10px 0; display: flex; align-items: center; } 
 .status span { margin-left: 10px; }
 .button { margin: 5px; padding: 10px; font-size: 16px; cursor: pointer; } 
 .input-group { margin-bottom: 20px; } 
 
 /* 指示灯样式 */
 .indicator {
   width: 20px;
   height: 20px;
   border-radius: 50%;
   margin-right: 5px;
   display: inline-block;
 }
 
 .green-light {
   background-color: green;
 }
 
 .red-light {
   background-color: red;
 }
 
 .flashing-light {
   animation: flash 1s infinite;
 }
 
 @keyframes flash {
   0%, 100% { opacity: 1; }
   50% { opacity: 0; }
 }
 </style> 
 <script> 
 // 默认的端口号 
 const apiPort = ':5000'; 
 let apiUrl = ''; // 将动态设置 
 
 function updateApiUrl() { 
 const userInput = document.getElementById('espIp').value; 
 if (userInput) { 
 apiUrl = `http://${userInput}${apiPort}`; 
 // 更新状态显示 
 fetchStatus(); 
 } else { 
 alert('Please enter a valid IP address.'); 
 } 
 } 
 
// 引入一个全局变量来存储状态数据
let esp32Status = {};

function fetchStatus() {
    if (!apiUrl) {
        alert('Please set the ESP32 IP address first.');
        return;
    }
    fetch(`${apiUrl}/status`)
        .then(response => response.json())
        .then(data => {
            // 将获取到的状态数据存储在全局变量中
            esp32Status = data;
            updateIndicator('highAlertStatus', data.HighAlert === 0 && data.Silence === 0 ? 'green-light' : '');
            document.getElementById('highAlertStatus').innerText = data.HighAlert === 1 ? 'On' : 'Off';
            
            updateIndicator('alertStatus', data.Alert === 1 && data.Silence === 0 ? 'red-light' : '');
            document.getElementById('alertStatus').innerText = data.Alert === 1 ? 'On' : 'Off';
            
            updateIndicator('silenceStatus', data.Silence === 1 ? 'green-light' : '');
            document.getElementById('silenceStatus').innerText = data.Silence === 1 ? 'On' : 'Off';
        })
        .catch(error => console.error('Error fetching status:', error));
}

function updateIndicator(elementId, className) {
    const span = document.querySelector(`#${elementId}`);
    const parent = span.parentElement;
    const existingLight = parent.querySelector('.indicator');
    
    if (className) {
        if (!existingLight) {
            const light = document.createElement('div');
            light.classList.add('indicator', className);
            parent.insertBefore(light, span);
        } else {
            existingLight.classList.remove('green-light', 'red-light', 'flashing-light');
            existingLight.classList.add(className);
        }
    } else {
        if (existingLight) {
            parent.removeChild(existingLight);
        }
    }
    
    // 使用全局变量esp32Status来判断是否需要添加闪烁效果
    if (elementId === 'highAlertStatus' && esp32Status.HighAlert === 0 && esp32Status.Silence === 0) {
        const light = parent.querySelector('.indicator');
        if (light) {
            light.classList.add('flashing-light');
        }
    } else {
        const light = parent.querySelector('.indicator.flashing-light');
        if (light) {
            light.classList.remove('flashing-light');
        }
    }
}

 // 由于data在updateIndicator外部无法直接访问，我们需要稍微修改fetchStatus函数以传递data给updateIndicator
 // 但为了简化示例，这里我们假设已经在全局或闭包中处理了data的传递，或者通过其他方式同步状态。
 // 在实际代码中，您可能需要重构这部分逻辑以确保data的正确传递和使用。
 // 由于这里的示例目的，我们省略了直接传递data的修改，而是假设了一种处理方式。
 // 注意：下面的setAlertStatus和setSilenceStatus函数没有直接受到这个问题的影响，因为它们不依赖于fetchStatus的data。

 // 设置警报状态的函数 
 function setAlertStatus(status) { 
 if (!apiUrl) { 
 alert('Please set the ESP32 IP address first.'); 
 return; 
 } 
 fetch(`${apiUrl}/alert?status=${status}`) 
 .then(response => response.text()) 
 .then(text => {
   console.log(text);
   fetchStatus(); // 重新获取状态以更新指示灯
 }) 
 .catch(error => console.error('Error setting alert status:', error)); 
 } 
 
 // 设置静默状态的函数 
 function setSilenceStatus(status) { 
 if (!apiUrl) { 
 alert('Please set the ESP32 IP address first.'); 
 return; 
 } 
 fetch(`${apiUrl}/silence?status=${status}`) 
 .then(response => response.text()) 
 .then(text => {
   console.log(text);
   fetchStatus(); // 重新获取状态以更新指示灯
 }) 
 .catch(error => console.error('Error setting silence status:', error)); 
 } 
 
 // 页面加载时显示提示 
 window.onload = function() { 
 alert('Please enter the IP address of your ESP32 below and click "Set IP" to connect.'); 
 }; 
 </script> 
</head> 
<body> 
 <h1>ESP32 Control Panel</h1> 
 <div class="input-group"> 
 <label for="espIp">ESP32 IP Address:</label> 
 <input type="text" id="espIp" placeholder="Enter IP address"> 
 <button class="button" onclick="updateApiUrl()">Set IP</button> 
 </div> 
 <div class="status" id="highAlertStatus-container">High Alert: <span></span></div> 
 <div class="status" id="alertStatus-container">Alert: <span></span></div> 
 <div class="status" id="silenceStatus-container">Silence: <span></span></div> 
 <button class="button" onclick="setAlertStatus(1)">Set Alert On</button> 
 <button class="button" onclick="setAlertStatus(0)">Set Alert Off</button> 
 <button class="button" onclick="setSilenceStatus(1)">Set Silence On</button> 
 <button class="button" onclick="setSilenceStatus(0)">Set Silence Off</button> 
 
 <script>
 // 由于HTML中的span没有id，我们通过父容器来定位并更新指示灯和状态文本
 // 这里我们给每个状态行添加了一个唯一的id（如highAlertStatus-container），并在JavaScript中使用它
 const highAlertContainer = document.getElementById('highAlertStatus-container');
 highAlertContainer.querySelector('span').id = 'highAlertStatus'; // 设置内部span的id以便后续使用
 
 const alertContainer = document.getElementById('alertStatus-container');
 alertContainer.querySelector('span').id = 'alertStatus';
 
 const silenceContainer = document.getElementById('silenceStatus-container');
 silenceContainer.querySelector('span').id = 'silenceStatus';
 </script>
</body> 
</html>